package com.yorick.common.util;

import com.alibaba.fastjson.JSONArray;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * @program: YorickUtil
 * @description: 自定义工具类
 * @author: Yorick
 * @create: 31/5/2022
**/
@Slf4j
@Component
public class YorickUtil {

    public static String listToString(List<String> list){
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<list.size();i++){
           sb.append(list.get(i));
           if(i!=list.size()-1){
               sb.append(",");
           }
        }
        return sb.toString();
    }

    public static String listToString(JSONArray list){
        StringBuffer sb=new StringBuffer();
        for(int i=0;i<list.size();i++){
            sb.append(list.get(i));
            if(i!=list.size()-1){
                sb.append(",");
            }
        }
        return sb.toString();
    }
    /**
     * 解压文件
     * @param zipPath 要解压的目标文件
     * @param descDir 指定解压目录
     * @return 解压结果：成功，失败
     */
    @SuppressWarnings("rawtypes")
    public static boolean decompressZip(String zipPath, String descDir) {
        File zipFile = new File(zipPath);
        boolean flag = false;
        File pathFile = new File(descDir);
        if(!pathFile.exists()){
            pathFile.mkdirs();
        }
        ZipFile zip = null;
        try {
            zip = new ZipFile(zipFile, Charset.forName("gbk"));//防止中文目录，乱码
            for(Enumeration entries = zip.entries(); entries.hasMoreElements();){
                ZipEntry entry = (ZipEntry)entries.nextElement();
                String zipEntryName = entry.getName();
                InputStream in = zip.getInputStream(entry);
                //指定解压后的文件夹+当前zip文件的名称
                String outPath = (descDir+zipEntryName).replace("/", File.separator);
                //判断路径是否存在,不存在则创建文件路径
                File file = new File(outPath.substring(0, outPath.lastIndexOf(File.separator)));
                if(!file.exists()){
                    file.mkdirs();
                }
                //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                if(new File(outPath).isDirectory()){
                    continue;
                }
                //保存文件路径信息（可利用md5.zip名称的唯一性，来判断是否已经解压）
                log.info(String.format("当前zip解压之后的路径为：%s",outPath));
                OutputStream out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[2048];
                int len;
                while((len=in.read(buf1))>0){
                    out.write(buf1,0,len);
                }
                in.close();
                out.close();
            }
            flag = true;
            //必须关闭，要不然这个zip文件一直被占用着，要删删不掉，改名也不可以，移动也不行，整多了，系统还崩了。
            zip.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static boolean compile(String command){
        try {
            Runtime r = Runtime.getRuntime();
            //执行linux命令，不关心返回结果，此处，可以执行一个shell脚本，或者python脚本
            Process p = r.exec(command);
            p.waitFor();
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }


    public static void saveFile(String filepath,byte [] bs)throws IOException{
        OutputStream out = new FileOutputStream(filepath);
        InputStream is = new ByteArrayInputStream(bs);
        byte[] buff = new byte[1024];
        int len = 0;
        while((len=is.read(buff))!=-1){
            out.write(buff, 0, len);
        }
        is.close();
        out.close();
    }

    //将json的value转成java byte数组
    public static byte[] jsonStringToBytes(String bytes) {
        Gson gson=new Gson();
        List<Byte> list = gson.fromJson(bytes,
                new TypeToken<List<Byte>>() {}.getType());
        if (list == null || list.size() < 0)
            return null;
        byte[] bytes1 = new byte[list.size()];
        int i = 0;
        Iterator<Byte> iterator = list.iterator();
        while (iterator.hasNext()) {
            bytes1[i] = iterator.next();
            i++;
        }
        return bytes1;
    }

    public static Map<String,String> getFolderFileHashes(String folderPath) throws Exception {
        Map<String,String> fileHashes = new HashMap<>();

        File folder = new File(folderPath);

        if (folder.exists() && folder.isDirectory()) {
            for (File file : folder.listFiles()) {
                if (file.isFile()) {
                    String fileHash = getFileHash(file);
                    fileHashes.put(fileHash,file.getName());
                }
            }
        }
        return fileHashes;
    }


    public static String getFileHash(File file) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");

        FileInputStream fis = new FileInputStream(file);

        byte[] dataBytes = new byte[1024];
        int bytesRead;

        while ((bytesRead = fis.read(dataBytes)) != -1) {
            md.update(dataBytes, 0, bytesRead);
        }

        byte[] hashBytes = md.digest();

        StringBuilder sb = new StringBuilder();
        for (byte hashByte : hashBytes) {
            sb.append(Integer.toString((hashByte & 0xff) + 0x100, 16).substring(1));
        }

        fis.close();

        return sb.toString();
    }
}
